package com.ztjava.upload.service;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Set;

import net.coobird.thumbnailator.Thumbnails;

import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaoleilu.hutool.date.DateUtil;
import com.ztjava.core.Constant;
import com.ztjava.core.Jsub;
import com.ztjava.core.base.BaseService;
import com.ztjava.core.tool.ViewTool;
import com.ztjava.core.utiliy.StringUtil;
import com.ztjava.upload.bean.UploadBean;
import com.ztjava.upload.cloud.QiniuSdk;
//import com.ztjava.upload.cloud.QiniuSdk;
import com.ztjava.upload.model.UploadFiles;

public class UploadService extends BaseService{
	/***
	 * 后台单文件上传令牌
	 * @param user_id
	 * @param plugin
	 * @param component
	 * @param model
	 * @param object_id
	 * @return
	 */
	public String makeUploadToken(Integer user_id,String plugin,String component,String model,Integer object_id){
		return makeUploadToken(user_id, plugin, component, model, object_id,
				"T", "T", null, 1, 0l, 0l);
	}
	/***
	 * 
	 * @param user_id 归属用户
	 * @param plugin 插件
	 * @param component 组建
	 * @param model 模型
	 * @param object_id 
	 * @param is_static 
	 * @param is_yun 
	 * @param exts 允许扩展名
	 * @param limit_amount 允许上传数量
	 * @param limit_size 限制大小 K
	 * @param thumbnails_size 大于压缩，K
	 * @return
	 */
	public String makeUploadToken(Integer user_id,
			String plugin,String component,String model,Integer object_id,String is_static,String is_yun,
			String exts,Integer limit_amount,Long limit_size,Long thumbnails_size){
		String token = DateUtil.format(new Date(),"yyyyMMddHHmmss")+StringUtil.getRandomString(12);
		UploadBean uploadBean = new UploadBean();
		uploadBean.setToken(token);
		uploadBean.setUser_id(user_id);
		uploadBean.setPlugin(plugin);
		uploadBean.setComponent(component);
		uploadBean.setModel(model);
		uploadBean.setObject_id(object_id);
		uploadBean.setIs_static(is_static);
		uploadBean.setIs_yun(is_yun);
		uploadBean.setExts(exts);
		uploadBean.setLimit_amount(limit_amount);
		uploadBean.setLimit_size(limit_size);
		uploadBean.setThumbnails_size(thumbnails_size);
		Cache cache = Redis.use();
		cache.setex(Constant.R_PRE+"UPLOAD:FILES:TOKEN:"+token, 60*60*24, uploadBean);
		
		if(limit_amount>0&&object_id!=null&&object_id>0){
			List<UploadFiles> list = UploadFiles.dao.find("select * from "+UploadFiles.tablename+" where plugin=? and component=? and model=? and object_id=? and status=?",
					uploadBean.getPlugin(),uploadBean.getComponent(),uploadBean.getModel(),uploadBean.getObject_id(),"USE");
			if(list.size()>0){
				for(int i=0;i<list.size();i++){
					cache.hset(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken(),
							list.get(i).getInt("id").toString(), list.get(i));
				}
			}
		}
		return token;
	}
	public UploadBean getFilesToken(String token){
		Cache cache = Redis.use();
		return cache.get(Constant.R_PRE+"UPLOAD:FILES:TOKEN:"+token);
	}
	/***
	 * 业务模块移除文件
	 * @param token
	 * @param user_id
	 * @param id
	 */
	public void removeFiles(String token,Integer id){
		Cache cache = Redis.use();
		if(cache.exists(Constant.R_PRE+"UPLOAD:FILES:ADD:"+token)){
			cache.hdel(Constant.R_PRE+"UPLOAD:FILES:ADD:"+token,id.toString());
			cache.hset(Constant.R_PRE+"UPLOAD:FILES:REMOVE:"+token,id.toString(),"T");
			//不直接删除，防止用户取消操作。
		}
	}
	/***
	 * 业务模块提交
	 * @param token
	 * @param user_id
	 * @param object_id
	 */
	public String submitFiles(String token,Integer user_id,Integer object_id){
		if(token==null||token.equals("")){
			return null;
		}
		Cache cache = Redis.use();
		String images = "";
		UploadBean uploadBean = getFilesToken(token);
		if(cache.exists(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken())){
			Set<Object> keysAdd = cache.hkeys(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken());
			for(Object key:keysAdd){
				UploadFiles uploadFiles = cache.hget(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken(), key);
				if(uploadFiles.get("cloud_url")!=null&&!uploadFiles.getStr("cloud_url").equals("")){
					images = images + uploadFiles.getStr("cloud_url")+",";
				}else {
					images = images + uploadFiles.getStr("local_url")+",";
				}
				Db.update("update "+UploadFiles.tablename+" set status=?,object_id=? where id=?","USE",object_id,Integer.parseInt(key.toString()));
			}
		}
		if(cache.exists(Constant.R_PRE+"UPLOAD:FILES:REMOVE:"+uploadBean.getToken())){
			Set<Object> keysRemove = cache.hkeys(Constant.R_PRE+"UPLOAD:FILES:REMOVE:"+uploadBean.getToken());
			for(Object key:keysRemove){
				Db.update("update "+UploadFiles.tablename+" set status=? where id=?","DELETE",Integer.parseInt(key.toString()));
			}
		}
		cache.del(Constant.R_PRE+"UPLOAD:FILES:TOKEN:"+uploadBean.getToken());
		cache.del(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken());
		cache.del(Constant.R_PRE+"UPLOAD:FILES:REMOVE:"+uploadBean.getToken());
		if(!images.equals("")){
			images = images.substring(0,images.length()-1);
		}
		return images;
	}
	/***
	 * 检查上传令牌
	 * @param uploadBean
	 * @param ext
	 * @param len
	 * @return
	 */
	public Ret checkUploadToken(UploadBean uploadBean,String ext,long len){
		if(uploadBean==null){
			return Ret.create(Constant.RESULT, Constant.ERROR).set(Constant.MESSAGE, "上传信息已失效");
		}
		if(uploadBean.getExts()!=null&&!uploadBean.getExts().equals("")){
			if(ext==null||uploadBean.getExts().indexOf(ext)==-1){
				return Ret.create(Constant.RESULT, Constant.ERROR).set(Constant.MESSAGE, "不支持的文件类型");
			}
		}
		if(uploadBean.getLimit_size()>0&&len>(uploadBean.getLimit_size()*1024)){
			return Ret.create(Constant.RESULT, Constant.ERROR).set(Constant.MESSAGE, "上传文件不得大于"+uploadBean.getLimit_size()+"KB");
		}
		//大于1则进行数量验证，等于1直接替换，不做验证
		if(uploadBean.getLimit_amount()!=null&&uploadBean.getLimit_amount()>1){
			Cache cache = Redis.use();
			Integer temp_size = cache.hlen(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken()).intValue();
			if(temp_size>=uploadBean.getLimit_size()){
				return Ret.create(Constant.RESULT, Constant.ERROR).set(Constant.MESSAGE, "上传文件不能多于"+uploadBean.getLimit_amount()+"个");
			}
		}
		return Ret.create(Constant.RESULT,Constant.SUCCESS);
	}
	 /***
	  * 插入文件记录
	  * @param uploadBean
	  * @param path
	  * @param name
	  * @param ext
	  * @param size
	  * @return
	  */
	public UploadFiles insertFiles(UploadBean uploadBean,Ret path,String name,String ext,long size){
		//看看是否需要压缩下
		thumbnails(ext, size, uploadBean.getThumbnails_size(), path.getStr("folder"));
		//看看是否需要传到云端
		String cloud_type = "NONE";
		String cloud_url = null;
		if(uploadBean.getIs_yun().equals("T")){
			cloud_type = ViewTool.param("UPLOAD_FILES_CLOUD_TYPE");
			if(cloud_type.equals("qiniu")){
				cloud_url = QiniuSdk.uploadFiles(path.getStr("folder"), path.getStr("url"));
			}
		}
		
		UploadFiles uploadFiles = new UploadFiles();
		uploadFiles.set("token", uploadBean.getToken());
		uploadFiles.set("plugin", uploadBean.getPlugin());
		uploadFiles.set("component", uploadBean.getComponent());
		uploadFiles.set("model", uploadBean.getModel());
		uploadFiles.set("object_id", uploadBean.getObject_id());
		uploadFiles.set("status", "NEW");
		uploadFiles.set("name", name);
		uploadFiles.set("ext", ext);
		uploadFiles.set("size", size);
		uploadFiles.set("local_url", path.getStr("url"));
		uploadFiles.set("local_address", path.getStr("folder"));
		uploadFiles.set("cloud_type", cloud_type);
		uploadFiles.set("cloud_url", cloud_url);
		uploadFiles.set("create_user", uploadBean.getUser_id());
		uploadFiles.save();
		//大于0，所以拿这个来检测下
		if(uploadBean.getLimit_amount()>0){
			Cache cache = Redis.use();
			//等于0，则先移除原来的，但不删除，防止用户取消操作。
			if(uploadBean.getLimit_amount()==1){
				if(cache.hlen(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken())>0){
					Set<Object> keys = cache.hkeys(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken());
					for(Object key:keys){
						cache.hdel(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken(),
								key.toString());
						cache.hset(Constant.R_PRE+"UPLOAD:FILES:REMOVE:"+uploadBean.getToken(),
								key.toString(),"T");
					}
				}
			}	
			cache.hset(Constant.R_PRE+"UPLOAD:FILES:ADD:"+uploadBean.getToken(), 
					uploadFiles.getInt("id").toString(), uploadFiles);
		}
		return uploadFiles;
	}

	/***
	 * 获取新文件路径
	 * @param uploadBean
	 * @param user_id
	 * @param ext
	 * @return
	 */
	public Ret getFilePath(UploadBean uploadBean,String ext){
		String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss")
				+StringUtil.getRandomString(10)+ext;
		String folder = File.separator + Jsub.upload_folder 
				+ File.separator + Jsub.folder 
				+ File.separator + uploadBean.getPlugin().toLowerCase()
				+ File.separator + uploadBean.getComponent().toLowerCase()
				+ File.separator + uploadBean.getModel().toLowerCase();
		
		if(uploadBean.getIs_static().equals("T")){
			folder = folder + File.separator + "static"
					+ File.separator + uploadBean.getUser_id()
					+ File.separator;
		}else {
			folder = folder + File.separator + DateUtil.format(new Date(), "yyyyMM")
					+ File.separator + uploadBean.getUser_id()
					+ File.separator; 
		}
				
		String url = folder.replace(File.separator, "/") + fileName;
		File dir = new File(Jsub.upload_path + folder);
		if (!dir.exists()) dir.mkdirs();
		Ret ret = Ret.create();
		ret.set("fileName", fileName);
		ret.set("folder", Jsub.upload_path + folder+fileName);
		ret.set("url", url);
		return ret;
	}
	/***
	 * 图片压缩
	 * @param ext
	 * @param len
	 * @param thumbnails_size
	 * @param filepath
	 */
	public void thumbnails(String ext,Long len,Long thumbnails_size,String filepath){
		if(".jpg,.jpeg,.png".indexOf(ext)==-1){
			return;
		}
		if(thumbnails_size==null||thumbnails_size==0){
			return;
		}
		if(len<=thumbnails_size*1024){
			return;
		}
		try {
			Thumbnails.of(filepath).scale(0.8f).allowOverwrite(true).toFile(filepath);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
